package com.gagakuai.engine.impl.interceptor.defaultImpl;

import com.gagakuai.engine.impl.cfg.ProcessEngineConfigurationImpl;
import com.gagakuai.engine.impl.context.Context;
import com.gagakuai.engine.impl.interceptor.Command;
import com.gagakuai.engine.impl.interceptor.CommandConfig;
import com.gagakuai.engine.impl.interceptor.CommandContext;

/*
 * @program: common-starters
 * @description: 命令上下文拦截器：初始化命令上下文
 * @author: houhong
 * @create: 2023-01-01 23:21
 */
public class CommandContextInterceptor extends AbstractCommandInterceptor {


    protected CommandContextFactory commandContextFactory;

    protected ProcessEngineConfigurationImpl processEngineConfiguration;

    public CommandContextInterceptor() {
    }

    public CommandContextInterceptor(CommandContextFactory commandContextFactory, ProcessEngineConfigurationImpl processEngineConfiguration) {
        this.commandContextFactory = commandContextFactory;
        this.processEngineConfiguration = processEngineConfiguration;
    }


    @Override
    public <T> T execute(CommandConfig config, Command<T> command) {

        CommandContext commandContext = Context.getCommandContext();

        boolean contextReused = false;
        if (!config.isContextReusePossible() || commandContext == null || commandContext.getException() != null) {

            commandContext = commandContextFactory.createCommandContext(command);
        } else {
            logger.debug("Valied commandContext found, " +
                    "Reusing it for the current command '{}'", command.getClass().getSimpleName());
            contextReused = true;
        }
        //入栈
        try {
            Context.setCommandContext(commandContext);
            Context.setProcessEngineConfiguration(processEngineConfiguration);

            getNext().execute(config, command);
        } finally {
            //从栈中移出
        }


        return null;
    }


    public CommandContextFactory getCommandContextFactory() {
        return commandContextFactory;
    }

    public void setCommandContextFactory(CommandContextFactory commandContextFactory) {
        this.commandContextFactory = commandContextFactory;
    }

    public ProcessEngineConfigurationImpl getProcessEngineConfiguration() {
        return processEngineConfiguration;
    }

    public void setProcessEngineConfiguration(ProcessEngineConfigurationImpl processEngineConfiguration) {
        this.processEngineConfiguration = processEngineConfiguration;
    }
}